﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace UtilZ.Dotnet.Ex.Communication.Net.Web
{
    /// <summary>
    /// http-内容类型-mime类型
    /// </summary>
    public class HttpContentTypes
    {
        /// <summary>
        /// key:文件扩展名;value:mime
        /// </summary>
        private readonly static Dictionary<string, string> _mimieDic = null;

        /// <summary>
        /// key:mime;value:文件扩展名
        /// </summary>
        private static Dictionary<string, string> _mimieDic2 = null;


        static HttpContentTypes()
        {
            ANY = @"*/*";
            STREAM = "application/octet-stream";
            TEXT = "text/plain";
            XML = "application/xml";
            JSON = "application/json";
            //XML = "text/xml";
            //JSON = "text/json";
            MULTIPART_BYTERANGES = "multipart/byteranges";

            var mimieDic = new Dictionary<string, string>();

            //二进制
            mimieDic.Add(".*", "application/octet-stream");
            mimieDic.Add(".exe", "application/x-msdownload");
            mimieDic.Add(".dll", "application/x-msdownload");

            //office
            mimieDic.Add(".docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document");
            mimieDic.Add(".doc", "application/msword");
            mimieDic.Add(".xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            mimieDic.Add(".xls", "application/x-xls");
            mimieDic.Add(".pptx", "application/vnd.openxmlformats-officedocument.presentationml.presentation");
            mimieDic.Add(".ppt", "application/vnd.ms-powerpoint");
            mimieDic.Add(".pdf", "application/pdf");
            mimieDic.Add(".rtf", "text/rtf");
            mimieDic.Add(".rtfd", "text/rtfd");
            mimieDic.Add(".odt", "application/vnd.oasis.opendocument.text");
            mimieDic.Add(".pot", "application/vnd.ms-powerpoint");


            //text-mdn
            mimieDic.Add(".txt", "text/plain");
            mimieDic.Add(".html", "text/html");
            mimieDic.Add(".htm", "text/html");
            mimieDic.Add(".js", "text/javascript");
            mimieDic.Add(".css", "text/css");

            mimieDic.Add(".php", "text/x-php");
            mimieDic.Add(".jsp", "text/html");
            mimieDic.Add(".mhtml", "message/rfc822");
            mimieDic.Add(".xhtml", "application/xhtml+html");
            mimieDic.Add(".xml", "application/xml");
            mimieDic.Add(".json", "application/json");
            mimieDic.Add(".py", "text/x-python");
            mimieDic.Add(".rb", "text/x-ruby");
            mimieDic.Add(".sh", "text/x-shellscript");
            mimieDic.Add(".pl", "text/x-perl");
            mimieDic.Add(".sql", "text/x-sql");
            mimieDic.Add(".java", "text/x-java-source");



            //图片-mdn
            mimieDic.Add(".gif", "image/gif");
            mimieDic.Add(".png", "image/png");
            mimieDic.Add(".jpeg", "image/jpeg");
            mimieDic.Add(".bmp", "image/x-ms-bmp");
            mimieDic.Add(".webp", "image/webp");
            //mimieDic.Add(".", "image/vnd.microsoft.icon");

            mimieDic.Add(".jpg", "image/jpeg");
            mimieDic.Add(".ico", "image/x-icon");
            mimieDic.Add(".tif", "image/tiff");
            mimieDic.Add(".tiff", "image/tiff");
            mimieDic.Add(".tga", "image/x-targa");
            mimieDic.Add(".psd", "image/vnd.adobe.photoshop");



            //音频-mdn
            mimieDic.Add(".mid", "audio/midi");
            mimieDic.Add(".mp3", "audio/mpeg");
            //mimieDic.Add(".ogg", "audio/ogg");
            //mimieDic.Add(".webm", "audio/webm");
            mimieDic.Add(".wav", "audio/wav");

            mimieDic.Add(".mp2", "audio/mp2");
            mimieDic.Add(".wma", "audio/x-ms-wma");


            //视频-mdn
            mimieDic.Add(".webm", "vidio/webm");
            mimieDic.Add(".ogg", "vidio/ogg");

            mimieDic.Add(".avi", "video/x-msvideo");
            mimieDic.Add(".mp4a", "audio/mp4");
            mimieDic.Add(".dv", "video/x-dv");
            mimieDic.Add(".mp1", "audio/mp1");
            mimieDic.Add(".mp2v", "video/mpeg");
            mimieDic.Add(".mp4", "video/mp4");
            mimieDic.Add(".mpeg", "video/mpeg");
            mimieDic.Add(".mpg", "video/mpeg");
            mimieDic.Add(".mov", "video/quicktime");
            mimieDic.Add(".wm", "video/x-ms-wmv");
            mimieDic.Add(".swf", "application/x-shockwave-flash");
            mimieDic.Add(".flv", "video/x-flv");
            mimieDic.Add(".mkv", "video/x-matroska");

            //压缩
            mimieDic.Add(".gz", "application/x-gzip");
            mimieDic.Add(".tgz", "application/x-gzip");
            mimieDic.Add(".bz", "application/x-bzip2");
            mimieDic.Add(".bz2", "application/x-bzip2");
            mimieDic.Add(".tbz", "application/x-bzip2");
            mimieDic.Add(".zip", "application/zip");
            mimieDic.Add(".rar", "application/x-rar");
            mimieDic.Add(".tar", "application/x-tar");
            mimieDic.Add(".7z", "application/x-7z-compressed");
            mimieDic.Add(".apk", "application/vnd.android.package-archive");

            _mimieDic = mimieDic;
        }


        /// <summary>
        /// 添加mime映射
        /// </summary>
        /// <param name="extension">扩展名</param>
        /// <param name="contentTypeOrMime">内容类型或mime</param>
        public static void AddMimeMapping(string extension, string contentTypeOrMime)
        {
            _mimieDic[extension] = contentTypeOrMime;

            if (_mimieDic2 != null)
            {
                _mimieDic2[contentTypeOrMime] = extension;
            }
        }

        /// <summary>
        /// 清空mime映射
        /// </summary>
        public static void Clear()
        {
            _mimieDic.Clear();

            if (_mimieDic2 != null)
            {
                _mimieDic2.Clear();
            }
        }

        /// <summary>
        /// 获取mimie映射,如果未配置映射,则返回二进制流(application/octet-stream)
        /// </summary>
        /// <param name="extension">文件路径或文件名</param>
        /// <returns>mimie映射</returns>
        public static string GetMimeMapping(string extension)
        {
            if (string.IsNullOrWhiteSpace(extension))
            {
                throw new ArgumentNullException(nameof(extension));
            }

            if (_mimieDic.TryGetValue(extension, out string mime))
            {
                return mime;
            }

            //默认二进制流，不知道下载文件类型,application/octet-stream
            return STREAM;
        }

        /// <summary>
        /// 根据内容类型或mime获取文件扩展名
        /// </summary>
        /// <param name="contentTypeOrMime">内容类型或mime</param>
        /// <returns>文件扩展名</returns>
        /// <exception cref="ArgumentNullException">内容类型或mime为空将抛出此异常</exception>
        public static string GetFileExtension(string contentTypeOrMime)
        {
            if (string.IsNullOrWhiteSpace(contentTypeOrMime))
            {
                throw new ArgumentNullException(nameof(contentTypeOrMime));
            }

            if (_mimieDic2 == null)
            {
                _mimieDic2 = new Dictionary<string, string>();
                foreach (var kv in _mimieDic)
                {
                    _mimieDic2[kv.Value] = kv.Key;
                }
            }

            string extension;
            _mimieDic2.TryGetValue(contentTypeOrMime, out extension);
            return extension;
        }





        #region 常见文件扩展体格式类型
        /// <summary>
        /// 任意
        /// </summary>
        public static string ANY = null;

        /// <summary>
        /// 二进制流数据
        /// </summary>
        public static string STREAM = null;

        /// <summary>
        /// 纯文本格式
        /// </summary>
        public static string TEXT = null;

        /// <summary>
        /// XML格式
        /// </summary>
        public static string XML = null;

        /// <summary>
        /// JSON数据格式
        /// </summary>
        public static string JSON = null;

        /// <summary>
        /// 多重范围请求时响应类型 
        /// </summary>
        public static string MULTIPART_BYTERANGES = null;

        /*
        /// <summary>
        /// form encType中默认的encType，form表单数据被编码为key/value格式发送到服务器
        /// （表单默认的提交数据的格式）另外一种常见的媒体格式是上传文件之时使用的
        /// </summary>
        [DisplayNameEx("form表单中默认的encType", "<form encType =””>中默认的encType，form表单数据被编码为key/value格式发送到服务器（表单默认的提交数据的格式）另外一种常见的媒体格式是上传文件之时使用的")]
        public static string FORM_URLENCODED = "application/x-www-form-urlencoded";

        /// <summary>
        ///  需要在表单中进行文件上传时，就需要使用该格式
        /// </summary>
        [DisplayNameEx("需要在表单中进行文件上传时", "需要在表单中进行文件上传时，就需要使用该格式")]
        public static string FORM_UPLOAD_FILE = "multipart/form-data";
         */
        #endregion
    }
}
